﻿using System;
using System.Collections.Generic;
using System.Text;

using Future.Contract;
using System.Data;

namespace Future.DataAccess
{
    public class AutoCreateSQLStatement
    {
        private BaseEntity _BaseEntity;
        public BaseEntity Entity
        {
            get { return _BaseEntity; }
            set { _BaseEntity = value; }
        }

        private string _SelectSQL = string.Empty;
        private string _InsertSQL = string.Empty;
        private string _DeleteSQL = string.Empty;
        private string _UpdateSQL = string.Empty;

        public AutoCreateSQLStatement(BaseEntity entity)
        {
            Entity = entity;
        }

        public virtual string SimpleSelectStatement
        {
            get
            {
                if (string.IsNullOrEmpty(_SelectSQL))
                {
                    StringBuilder strSQL = new StringBuilder(" SELECT ");

                    foreach (System.Reflection.PropertyInfo item in Entity.GetType().GetProperties())
                    {
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs == null || objs.Length == 0) { continue; }
                        DBColumnAttribue pAttribute = objs[0] as DBColumnAttribue;
                        if (pAttribute != null && pAttribute.IsDBColumn == true && pAttribute.IsSelect)
                        {
                            strSQL.Append(" [" + item.Name.ToUpper() + "],");
                        }
                    }
                    strSQL = strSQL.Remove(strSQL.Length - 1, 1);
                    strSQL.Append(" FROM [" + Entity.TABLE_NAME + "] ");
                    _SelectSQL = strSQL.ToString();
                }
                return _SelectSQL;
            }
        }

        public virtual string SimpleInsertStatement
        {
            get
            {
                if (string.IsNullOrEmpty(_InsertSQL))
                {
                    StringBuilder strSQL = new StringBuilder("INSERT INTO " + Entity.TABLE_NAME + " (");
                    StringBuilder strInsertHead = new StringBuilder(" ");
                    StringBuilder strInsertParm = new StringBuilder(" ");
                    foreach (System.Reflection.PropertyInfo item in Entity.GetType().GetProperties())
                    {
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs.Length == 0) { continue; }
                        DBColumnAttribue pAttribute = objs[0] as DBColumnAttribue;
                        if (pAttribute != null && pAttribute.IsDBColumn == true && pAttribute.IsInsert)
                        {
                            strInsertHead.Append(" " + item.Name.ToUpper() + ",");
                            strInsertParm.Append(" @" + item.Name.ToUpper() + ",");
                        }
                    }
                    strInsertHead = strInsertHead.Remove(strInsertHead.Length - 1, 1);
                    strInsertParm = strInsertParm.Remove(strInsertParm.Length - 1, 1);
                    strSQL.Append(strInsertHead.ToString() + ") VALUES (" + strInsertParm.ToString() + ")");
                    strSQL.Append(" SELECT @@IDENTITY; ");
                    _InsertSQL = strSQL.ToString();
                }
                return _InsertSQL;
            }
        }

        public virtual string SimpleUpdateStatement
        {
            get
            {
                if (string.IsNullOrEmpty(_UpdateSQL))
                {
                    StringBuilder strSQL = new StringBuilder("UPDATE  " + Entity.TABLE_NAME + " SET ");
                    foreach (System.Reflection.PropertyInfo item in Entity.GetType().GetProperties())
                    {
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs.Length == 0) { continue; }
                        DBColumnAttribue pAttribute = objs[0] as DBColumnAttribue;
                        if (pAttribute != null && pAttribute.IsDBColumn == true && pAttribute.IsUpdate && item.Name != Entity.PK)
                        {
                            strSQL.Append(" " + item.Name.ToUpper() + " = @" + item.Name + ",");
                        }
                    }
                    strSQL = strSQL.Remove(strSQL.Length - 1, 1);
                    strSQL.Append(" WHERE " + Entity.PK + " = @" + Entity.PK + " ");
                    _UpdateSQL = strSQL.ToString();
                }
                return _UpdateSQL;
            }
        }

        public virtual string SimpleDeleteStatement
        {
            get
            {
                if (string.IsNullOrEmpty(_DeleteSQL))
                {
                    StringBuilder strSQL = new StringBuilder("DELETE  FROM [" + Entity.TABLE_NAME + "] ");
                    StringBuilder strCondition = new StringBuilder("");
                    foreach (System.Reflection.PropertyInfo item in Entity.GetType().GetProperties())
                    {
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs.Length == 0) { continue; }
                        DBColumnAttribue pAttribute = objs[0] as DBColumnAttribue;
                        if (pAttribute != null && pAttribute.IsDBColumn == true && pAttribute.IsDelete)
                        {
                            strCondition.Append(" [" + item.Name.ToUpper() + "]= @" + item.Name + ",");
                        }
                    }
                    if (strCondition.Length <= 0)
                    {
                        //没有设置删除列 则默认为主键
                        strCondition.Append(" [" + Entity.PK.ToUpper() + "]= @" + Entity.PK + "");
                    }
                    else
                    {
                        strCondition = strCondition.Remove(strCondition.Length - 1, 1);
                    }
                    strSQL.Append(" WHERE " + strCondition);
                    _DeleteSQL = strSQL.ToString();
                }
                return _DeleteSQL;
            }
        }

        public virtual IDataParameter[] CreateParameter_Select(BaseEntity entity)
        {
            List<IDataParameter> parameter = new List<IDataParameter>();
            string tempCondition = " WHERE (1=1) ";
            if (entity != null)
            {
                try
                {
                    foreach (System.Reflection.PropertyInfo item in entity.GetType().GetProperties())
                    {
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs.Length == 0) { continue; }
                        DBColumnAttribue tempAttribue = objs[0] as DBColumnAttribue;
                        if (tempAttribue == null || !tempAttribue.IsDBColumn || !tempAttribue.IsSelect) { continue; }
                        object itemValue = item.GetValue(entity, null);
                        if (itemValue != null)
                        {
                            string itemString = itemValue.ToString();
                            if (string.IsNullOrEmpty(itemString))
                            {
                                continue;
                            }
                            if (item.Name == entity.PK)
                            {
                                tempCondition += " AND " + item.Name + " = @" + item.Name + " ";
                                parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, itemString, DbType.String));
                            }
                            else
                            {
                                switch (tempAttribue.DBType)
                                {
                                    case DbType.Int32:
                                    case DbType.Double:
                                    case DbType.Boolean:
                                        tempCondition += " AND " + item.Name + " = @" + item.Name + " ";
                                        parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, itemString, tempAttribue.DBType));
                                        break;
                                    case DbType.DateTime:
                                    case DbType.DateTime2:
                                        continue;
                                    default:
                                        tempCondition += " AND " + item.Name + " LIKE @" + item.Name + " ";
                                        parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, "%" + itemString + "%", DbType.String));
                                        break;
                                }

                            }

                        }
                    }
                    entity.ConditionStatement = tempCondition;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return parameter.ToArray();
        }

        public virtual IDataParameter[] CreateParameter_Insert(BaseEntity entity)
        {
            List<IDataParameter> parameter = new List<IDataParameter>();
            if (entity != null)
            {
                try
                {
                    foreach (System.Reflection.PropertyInfo item in entity.GetType().GetProperties())
                    {
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs.Length == 0) { continue; }
                        DBColumnAttribue tempAttribue = objs[0] as DBColumnAttribue;
                        if (tempAttribue == null || !tempAttribue.IsDBColumn || !tempAttribue.IsInsert) { continue; }
                        object itemValue = item.GetValue(entity, null);
                        if (itemValue != null)
                        {
                            string itemString = itemValue.ToString();
                            if (string.IsNullOrEmpty(itemString))
                            {
                                continue;
                            }
                            parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, itemString, tempAttribue.DBType));
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return parameter.ToArray();
        }

        public virtual IDataParameter[] CreateParameter_Update(BaseEntity entity)
        {
            List<IDataParameter> parameter = new List<IDataParameter>();
            if (entity != null)
            {
                try
                {
                    foreach (System.Reflection.PropertyInfo item in entity.GetType().GetProperties())
                    {
                        if (item.Name == entity.PK)
                        {
                            parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, entity.PK_VALUE, DbType.Int32));
                            continue;
                        }
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs.Length == 0) { continue; }
                        DBColumnAttribue tempAttribue = objs[0] as DBColumnAttribue;
                        if (tempAttribue == null || !tempAttribue.IsDBColumn || !tempAttribue.IsUpdate) { continue; }
                        object itemValue = item.GetValue(entity, null);
                        if (itemValue != null)
                        {
                            string itemString = itemValue.ToString();
                            if (string.IsNullOrEmpty(itemString))
                            {
                                continue;
                            }
                            parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, itemString, tempAttribue.DBType));
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return parameter.ToArray();
        }

        public virtual IDataParameter[] CreateParameter_Delete(BaseEntity entity)
        {
            List<IDataParameter> parameter = new List<IDataParameter>();
            if (entity != null)
            {
                try
                {
                    foreach (System.Reflection.PropertyInfo item in entity.GetType().GetProperties())
                    {
                        if (item.Name == entity.PK)
                        {
                            parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, entity.PK_VALUE, DbType.Int32));
                            continue;
                        }
                        object[] objs = item.GetCustomAttributes(typeof(DBColumnAttribue), true);
                        if (objs.Length == 0) { continue; }
                        DBColumnAttribue tempAttribue = objs[0] as DBColumnAttribue;
                        if (tempAttribue == null || !tempAttribue.IsDBColumn || !tempAttribue.IsDelete) { continue; }
                        object itemValue = item.GetValue(entity, null);
                        if (itemValue != null)
                        {
                            string itemString = itemValue.ToString();
                            if (string.IsNullOrEmpty(itemString))
                            {
                                continue;
                            }
                            parameter.Add(SqlDBOperator.shareSQLOperater().CreateParameter(item.Name, itemString, tempAttribue.DBType));
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return parameter.ToArray();
        }
    }
}
